/**
 * 
 */
package com.googlecode.rotools.grf;

import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;

abstract class TextParser<T> extends GrfParser<T>{
	private static final String CHARSET_MS932 = "MS932";
	private String charsetName;
	private int columns = 2;
	
	TextParser() {
		this(CHARSET_MS932, 2);
		
	}
	TextParser(int columns) {
		this(CHARSET_MS932, columns);
		
	}
	/**
	 * @param file
	 */
	TextParser(String charsetName) {
		super();
		this.charsetName = charsetName;
	}
	
	TextParser(String charsetName, int columns) {
		super();
		this.charsetName = charsetName;
		this.columns = columns;
	}
	
	@Override
	List<T> parse(byte[] data) throws IOException {
		return parse(new String(data, charsetName));
	}
	
	List<T> parse(String text)throws IOException{
		ArrayList<T> list = new ArrayList<T>();
		text = removeComments(text);
		String[][] rows = splitCells(text);
		for (String[] strings : rows) {
			//System.out.println(strings[0] + "," + strings[1]);
			for (int i = 0; i < strings.length; i++) {
				strings[i] = strings[i].trim(); 
			}
			list.add(parse(strings));
		}
		return list;
	}
	
	abstract T parse(String[] texts) throws IOException;
	
	private String removeComments(String text){
		StringBuffer stringBuffer = new StringBuffer(text.length());
		String[] strings = text.split("//.*\\r\\n");
		for (String string : strings) {
			stringBuffer.append(string);
		}
		return stringBuffer.toString();
	}
	
	protected String[][] splitCells(String text){
		ArrayList<String[]> list = new ArrayList<String[]>();
		try{
			Reader reader = new StringReader(text);
			try{
				String[] row = null;
				while(null != (row = nextRow(reader))){
					list.add(row);
				}
			}finally{
				reader.close();
			}
		}catch(IOException e){
			e.printStackTrace();
		}
		return list.toArray(new String[list.size()][]);
	}
	protected String[] nextRow(Reader reader) throws IOException{
		String[] strings = new String[columns];
		
		for (int i = 0; i < strings.length; i++) {
			strings[i] = nextCell(reader);
			if(null == strings[i]){
				return null;
			}			
		}
		return strings;
	}
	protected String nextCell(Reader reader) throws IOException{
		String string = null;
		boolean text = false;
		int n = reader.read();
		if(n != -1){
			StringBuffer buffer = new StringBuffer();
			do {
				char c = (char)n;
				if(c == '\''){
					buffer.append(c);
					text = !text;
					
				}else if(c == '\n' || c == '\r' ){
					if(text){
						text = !text; 
					}
					buffer.append(c);
					
				}else if((c == '#' || c == '＃')&& !text)
				{
					break;
					
				}else{
					buffer.append(c);
					
				}
			}while (-1 != (n = reader.read()));
			string = buffer.toString();
		}
		return string;
	}
}
